#include "SimulationWindow.h"

#include <QtGui>
//#include "NewParameters.hh"
#include <iostream>

SimulationWindow::SimulationWindow()
{
  QDoubleValidator *sci = new QDoubleValidator();

  simChoice = new QComboBox();
  QStringList strChoice;
  strChoice<<"Trajectory"<<"Phase Diagram"<<"Astroid"<<"Icrit vs Pulse Length"<<"Loop R(H)";
  simChoice->addItems(strChoice);

  QStackedWidget *simWidget = new QStackedWidget();
  QHBoxLayout *trajLayout = new QHBoxLayout();
  initialAngle = new QCheckBox("use angle");
  initialAngle->setToolTip("calculates the initial position without current and with an angle");
  trajAverage = new QCheckBox("Average last ns");
  trajAverage->setToolTip("average the magnetization during the last nanosecond in case of precession");
  trajLayout->addWidget(initialAngle);
  trajLayout->addWidget(trajAverage);
  QWidget *trajWidget = new QWidget();
  trajWidget->setLayout(trajLayout);

  QHBoxLayout *phdLayout = new QHBoxLayout();
  xAxis = new QComboBox();
  yAxis = new QComboBox();
  phdAverage = new QCheckBox("Average last 5ns");
  xAxis->addItem("Field vs Current");
  xAxis->addItem("Pulse Length vs Current");
  yAxis->addItem("Current");
  yAxis->addItem("Field");
  phdLayout->addWidget(xAxis);
  phdLayout->addWidget(phdAverage);
  //phdLayout->addWidget(yAxis);
  QWidget *phdWidget = new QWidget();
  phdWidget->setLayout(phdLayout);
  //QWidget *icLengthWidget = new QWidget();
  variousFields = new QCheckBox("for different fields");
  QLabel *astroid = new QLabel(" ");
  QLabel *loop = new QLabel(" ");
  astroid->hide();
  loop->hide();
  simWidget->addWidget(trajWidget);
  simWidget->addWidget(phdWidget);
  simWidget->addWidget(astroid);
  simWidget->addWidget(variousFields);
  simWidget->addWidget(loop);

  QGroupBox *timeBox = new QGroupBox("Time");
  QFormLayout *timeLayout = new QFormLayout();
  timeWindow = new QLineEdit();
  timeWindow->setValidator(sci);
  timeWindow->setToolTip("time of calculation in seconds");
  timeStep = new QLineEdit();
  timeStep->setValidator(sci);
  timeStep->setToolTip("time step for the Runge Kutta algorithm in seconds");
  maxTimeStep = new QLineEdit();
  maxTimeStep->setValidator(sci);
  maxTimeStep->setToolTip("maximum time step in seconds");
  timeLayout->addRow("Time Window",timeWindow);
  timeLayout->addRow("Time Step",timeStep);
  timeLayout->addRow("Maximum Time Step",maxTimeStep);
  timeBox->setLayout(timeLayout);

  QGroupBox *tempBox = new QGroupBox("Temperature");
  QFormLayout *tempLayout = new QFormLayout();
  temperature = new QSpinBox();
  temperature->setRange(0,1000);
  temperature->setToolTip("temperature in Kelvins");
  nbrun = new QSpinBox();
  nbrun->setToolTip("number of calculations");
  tempLayout->addRow("Temperature",temperature);
  tempLayout->addRow("Number of runs",nbrun);
  tempBox->setLayout(tempLayout);

  QGroupBox *torqueBox = new QGroupBox("Torque");
  QFormLayout *torqueLayout = new QFormLayout();
  limTorque = new QDoubleSpinBox();
  limTorque->setToolTip("below this torque value, the calculation is stopped");
  tolerance = new QSpinBox();
  tolerance->setToolTip("tolerance for the switching value in %");
  torqueLayout->addRow("limit",limTorque);
  torqueLayout->addRow("switching tolerance",tolerance);
  torqueBox->setLayout(torqueLayout);

  QGridLayout *layout = new QGridLayout(this);
  layout->addWidget(simChoice,0,0,1,1);
  layout->addWidget(simWidget,0,1,1,2);
  layout->addWidget(timeBox,1,0,3,1);
  layout->addWidget(tempBox,1,1,2,1);
  layout->addWidget(torqueBox,3,1,2,1);

  QObject::connect(simChoice,SIGNAL(activated(int)),simWidget,SLOT(setCurrentIndex(int)));
  QObject::connect(simChoice,SIGNAL(activated(int)),this,SLOT(emitSimChoice(int)));
  QObject::connect(xAxis,SIGNAL(activated(int)),this,SLOT(emitPhDChoice(int)));
  QObject::connect(variousFields,SIGNAL(clicked()),this,SLOT(emitHChoice()));
}

SimulationWindow::~SimulationWindow()
{

}

NewParameters SimulationWindow::getParameters(NewParameters params)
{
  QMap<QString,double> torqueParams,timeParams;
  params.setTemperature(temperature->value());
  params.setNbRun(nbrun->value());
  torqueParams["limit"]=limTorque->value();
  torqueParams["tolerance"]=tolerance->value();
  timeParams["window"]=timeWindow->text().toFloat();
  timeParams["step"]=timeStep->text().toFloat();
  timeParams["maxStep"]=maxTimeStep->text().toFloat();
  params.setTorque(torqueParams);
  params.setTime(timeParams);
  return params;
}

void SimulationWindow::emitSimChoice(int choice)
{
  QTextStream cout(stdout,QIODevice::WriteOnly);
  switch(choice)
    {
    case 0 :
      {
	emit constantIChoice();
	emit constantHChoice();
	emit constantLengthChoice();  
	break;
      }
    case 1 :
      {
	if(xAxis->currentIndex() == 0)
	  {
	    emit loopIChoice();
	    emit loopHChoice();
	  }
	else if (xAxis->currentIndex() == 1)
	  {
	    emit constantHChoice();
	    emit loopLengthChoice();
	  }
	break;
      }
    case 2 :
	{
	  emit astroidChoice();
	  break;
	}
    case 4 : //loop
	{
	  emit loopHChoice();
	  emit constantIChoice();
	  emit constantLengthChoice();
	  break;
	}
    case 3 : //ICrit vs pulse length
	{
	  emit loopLengthChoice();
	  //emit loopIChoice();
	  if(variousFields->isChecked())
	    {
	      emit loopHChoice();
	    }
	  else
	    {
	      emit constantHChoice();
	    }
	  break;
	}
    }
}

void SimulationWindow::emitPhDChoice(int choice)
{
  if(choice == 0)
    {
      //emit constantLengthChoice();
      emit loopIChoice();
      emit loopHChoice();
    }
  else if(choice == 1)
    {
      emit constantHChoice();
      //emit loopIChoice();
      emit loopLengthChoice();
    }
}

void SimulationWindow::emitHChoice()
{
  if(variousFields->isChecked())
    {
      emit loopHChoice();
    }
  else
    {
      emit constantHChoice();
    }
}

int SimulationWindow::getSimChoice()
{
  return simChoice->currentIndex();
}

QComboBox *SimulationWindow::getXAxis()
{
  return xAxis;
}

void SimulationWindow::loadParameters(NewParameters params)
{
  QString str;
  timeWindow->clear();
  timeStep->clear();
  maxTimeStep->clear();
  temperature->clear();
  nbrun->clear();
  limTorque->clear();
  tolerance->clear();
  timeWindow->insert(str.setNum(params.getTime()["window"]));
  timeStep->insert(str.setNum(params.getTime()["step"]));
  maxTimeStep->insert(str.setNum(params.getTime()["maxStep"]));
  tolerance->setValue(params.getTorque()["tolerance"]);
  limTorque->setValue(params.getTorque()["limit"]);
  temperature->setValue(params.getTemperature());
  nbrun->setValue(params.getNrun());
}

bool SimulationWindow::getPhDAverage()
{
  if(phdAverage->isChecked())
    {
      return true;
    }
  else
    {
      return false;
    }
}

bool SimulationWindow::getTrajAverage()
{
  if(trajAverage->isChecked())
    {
      return true;
    }
  else
    {
      return false;
    }
}

bool SimulationWindow::getVariousFields()
{
  if(variousFields->isChecked())
    {
      return true;
    }
  else
    {
      return false;
    }
}

bool SimulationWindow::getAngle()
{
  if(initialAngle->isChecked())
    {
      return true;
    }
  else
    {
      return false;
    }
}
